// UART Library for PIC 18F2550
// SDCC version / small device c compiler
// written by Jean-Pierre MANDON 2008 jp.mandon@free.fr
// www.pictec.org
/*
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

   In other words, you are welcome to use, share and improve this program.
   You are forbidden to forbid anyone else to use, share and improve
   what you give them.   Help stamp out software-hoarding!
*/
// this program is intended for an oscillator frequency of 20 Mhz


// SPBRG value for FOSC 20 Mhz

#define B300             1,0,0x27,0x0F
#define B1200            1,0,0x09,0xC3
#define B2400            1,0,0x04,0xE1
#define B4800			 1,0,0x02,0x70
#define B9600            0,0,0x00,0x4D
#define B19200           0,0,0x00,0x26
#define B57600           1,1,0x00,0xCF
#define B115200          1,1,0x00,0x67

// local definition UART.C

#define BUFFER 128                      // rx buffer length
char rx[BUFFER];                        // this is the buffer
unsigned char wpointer,rpointer;        // write and read pointer

#define charreceived (wpointer!=rpointer)
#define SERIAL

typedef struct
{
unsigned int
hhigh4:4,
hlow4:4,
lhigh4:4,
llow4:4;
} bitfield;

// setup PIC UART

void setup_UART(unsigned char brg16,unsigned char brgh,unsigned char highbyte,unsigned char lowbyte)
{
TXSTAbits.BRGH=brgh&1;                 	// set BRGH bit
BAUDCONbits.BRG16=brg16&1;		// set 16 bits SPBRG
SPBRGH=highbyte;                        // set UART speed SPBRGH
SPBRG=lowbyte;				// set UART speed SPBRGL
RCSTA=0x90;                             // set RCEN and SPEN
BAUDCONbits.RCIDL=1;			// set receive active
PIE1bits.RCIE=1;                        // enable interrupt on RX
INTCONbits.PEIE=1;                      // enable peripheral interrupts
IPR1bits.RCIP=0;                        // define low priority for RX interrupt
wpointer=1;                             // initialize write pointer
rpointer=1;                             // initialize read pointer
TXSTAbits.TXEN=1;                       // enable TX
INTCONbits.GIE=1;
}

// UART write char

void Printf(unsigned char caractere)
{
while (!TXSTAbits.TRMT);
TXREG=caractere;		        // yes, send char
}

// rxint is called by interruption service routine

void rxint(void)
{
char caractere;
unsigned char newwp;

     PIR1bits.RCIF=0;                   // clear RX interrupt flag
     caractere=RCREG;                   // take received char
     if (wpointer!=BUFFER-1)            // if not last place in buffer
	newwp=wpointer+1;               // place=place+1
     else
	newwp=1;                        // else place=1

     if (rpointer!=newwp)               // if read pointer!=write pointer
	rx[wpointer++]=caractere;       // store received char

     if (wpointer==BUFFER)              // if write pointer=length buffer
	 wpointer=1;                    // write pointer = 1
}


// get char

unsigned char getch()
{
unsigned char caractere=0;

if (charreceived)
    {
    caractere=rx[rpointer++];
    if (rpointer==BUFFER)
	rpointer=1;
    }
return(caractere);
}

// clear rx buffer

void clear_buffer(void) {
wpointer=1;
rpointer=1;
}

// write a string on the UART

void Print_str(const char* text)
{
unsigned char i=0;
while ( text[i] != 0 )
    Printf( text[i++] );
}

// convert 16 bits binary value  to DEC and send it on the UART

void Print_dec(unsigned int valeur)
{
unsigned char result;
unsigned char zero=1;


result=valeur/10000;
if (result!=0)  {
		Printf(result+0x30);
		zero=0;
		}
valeur=valeur%10000;
result=valeur/1000;
if (result!=0)  {
		Printf(result+0x30);
		zero=0;
		}
else if (zero==0) Printf('0');
valeur=valeur%1000;
result=valeur/100;
if (result!=0)  {
		Printf(result+0x30);
		zero=0;
		}
else if (zero==0) Printf('0');
valeur=valeur%100;
result=valeur/10;
if (result!=0)  {
		Printf(result+0x30);
		zero=0;
		}
else if (zero==0) Printf('0');
result=valeur%10;
Printf(result+0x30);
}

// convert 16 bits binary value to HEX and send it on the UART

void Print_hex(unsigned int valeur)
{
  const char hexa[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

Printf(hexa[(valeur>>12)&0x000F]);
Printf(hexa[(valeur>>8)&0x000F]);
Printf(hexa[(valeur>>4)&0x000F]);
Printf(hexa[valeur&0x000F]);
}

// convert 16 bits binary value to byte and send it on the UART

void Print_byte(unsigned int valeur)
{
unsigned int result;
result=valeur;
Printf(result);
}


